#pragma once
#include "Comm.h"
#include "Buffer.h"
#include "ThreadSemaphore.h"
#include "ThreadLock.h"
#include "List.h"

namespace COMM
{
#ifdef COMM_MSVC
	template class COMM_API stdlist<Buffer*>;
	template class COMM_API List<Buffer*, ThreadNullLock>;
#endif

	class COMM_API MessageQueue : public ThreadLock
	{
	public:
		MessageQueue(size_t maxCapacity=-1); // maxCapacity: max size of total buffer.
		~MessageQueue(void);

		// return false if full or waiting timeout.
		bool Push(const void* ptr, size_t size, bool atFront=false, unsigned int timeoutMs=-1);
		bool Push(const Buffer& buffer, bool atFront=false, unsigned int timeoutMs=-1);
		// return NULL if timeout.
		// the returned value must be free by yourself.
		// ScopedPtr<Buffer> could be used to free automatic.
		Buffer* Pop(unsigned int timeoutMs = -1, bool atFront=true);
		// return NULL if empty.
		// the returned value can not be free.
		Buffer* Peek(bool atFront=true);
		// get current capacity of total buffer.
		size_t Capacity();
		// get current buffer count.
		size_t Count();
		// convert total buffer to flat buffer.
		void Flat(Buffer& buffer);
		// clear all the buffer.
		void Clear();

	private:
		List<Buffer*,ThreadNullLock> m_bufferList;
		ThreadSemaphore m_sem;
		size_t m_maxCapacity;
		size_t m_currentCapacity;
	};
}


